#!/bin/ash -efu

. shell-string

# http://ru.wikipedia.org/wiki/CRC32#CRC-32
# http://rosettacode.org/wiki/CRC-32
#
# Name  : CRC-32
# Poly  : 0x04C11DB7    x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 
#                       + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
# Init  : 0xFFFFFFFF
# Revert: true
# XorOut: 0xFFFFFFFF
# Check : 0xCBF43926 ("123456789")
#

shell_crc32()
{
	local __shell_crc32_crc

__shell_crc32()
{
	unset -f __shell_crc32

	local i n val crc=$(( 0xFFFFFFFF ))
	while read n; do
		val=$(( ($crc & 0xFF) ^ $n ))
		i=0
		while [ $i -lt 8 ]; do
			[ $(( $val & 1 )) -ne 0 ] &&
				val=$(( ($val >> 1) ^ 0xEDB88320 )) ||
				val=$(( ($val >> 1) ))
			i=$(( $i + 1 ))
		done
		crc=$(( ($crc >> 8) ^ $val ))
	done <<-EOF
		`
	buf="$1"
	fill_mask mask "$buf"
	while [ -n "$buf" ]; do
		printf '%u\n' "'${buf%$mask}"
		buf=${buf#?}
		mask=${mask#?}
	done`
	EOF
	__shell_crc32_crc=$(( $crc ^ 0xFFFFFFFF ))
}
	__shell_crc32 "$2"
	eval "$1=\"\$__shell_crc32_crc\""
}

str="123456789"
echo "CBF43926"
shell_crc32 "res" "$str"
printf '%X\n' $res
